/* 
 * File:   crash.cpp
 * Author: ScaV
 *
 * Created on Oct 31, 2011, 7:50:28 PM
 */

#include "scanner.h"
#include "tables.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <windows.h>

using namespace std;

/*
 * Simple C++ Test Suite
 */

void test1() {
	std::cout << "crash test" << std::endl;
	try {
		
	char infile[]="crash_in.txt", outfile[] = "crash_out.txt";
	
	lexeme *lx;
	vector<lexeme*> result;
	vector<lexeme*>::iterator iter;
	scanner a(infile);
	tables table(2, 2, 2, 2, 2);
	char *name, *type;
	ofstream maintable;
	
//Build tables
	for (int i = 0; !a.eof() ; ++i) {
		lx = a.getNextLex();
		if (!lx)
			break;
		result.push_back(lx);
	}
	maintable.open(outfile, ios::out);
	if (!maintable.is_open())
		throw "Can't open main output file!";
//Output to files
	for (iter = result.begin(); iter != result.end(); ++iter) {
		lx = *iter;
		name = lx->getName();
		type = lx->getType();
		maintable << lx->line
				<< "\t" << type
				<< "\t\t\t<" << name
				<< ">" << endl;
		delete[] name;
		delete[] type;
	}
	maintable.close();
} catch (const char *str) {
	std::cout << "%TEST_FAILED% time=0 testname=Crash (crash) message=" << str << std::endl;
}
try {
	lexeme *lx1, *lx2;
	tables table(1, 1, 1, 1, 1);
	std::vector<lexeme*> result1, result2;
	scanner in("crash_out.txt"), out("crash_templateout.txt");
	for (int i = 0; ; ++i) {
		if (in.eof() != out.eof())
			throw "Different file's sizes!";
		else if (in.eof())
			break;
		lx1 = in.getNextLex();
		lx2 = out.getNextLex();
		if (!lx1 || !lx2) {
			if (lx1 != lx2)
				throw "Different file's sizes!";
			break;
		}
		result1.push_back(lx1);
		result2.push_back(lx2);
		table.add(lx1);
	}
	std::vector<lexeme*>::iterator iter1, iter2;
	iter1 = result1.begin();
	iter2 = result2.begin();
	char *str1, *str2;
	long sizes[5], nsizes[5];
	sizes[0] = table.constant->getSize();
	sizes[1] = table.identificator->getSize();
	sizes[2] = table.keyword->getSize();
	sizes[3] = table.separator->getSize();
	sizes[4] = table.unknown->getSize();
	while (1) {
		if (iter1 == result1.end() || iter2 == result2.end()) {
			if (iter1 != result1.end() || iter2 != result2.end())
				throw "Different crashout file's sizes!";
			break;
		}
		lx1 = *iter1;
		lx2 = *iter2;
		str1 = lx1->getName();
		str2 = lx2->getName();
		
		if (strcmp(str1, str2))
			throw "Different lexemes!";
		if (lx1->line != lx2->line)
			throw "Different lines!";
		if (lx1->type != lx2->type)
			throw "Different types!";
		
		table.add(lx2);
		
		++iter1;
		++iter2;
	}
	nsizes[0] = table.constant->getSize();
	nsizes[1] = table.identificator->getSize();
	nsizes[2] = table.keyword->getSize();
	nsizes[3] = table.separator->getSize();
	nsizes[4] = table.unknown->getSize();
	for (int m = 0; m < 5; ++m)
		if (nsizes[m] != sizes[m])
			throw "Tablesize changes!";
	return;
} catch (const char *str) {
	std::cout << "%TEST_FAILED% time=0 testname=Crash (crash) message=" << str << std::endl;
}
}

int main(int argc, char** argv) {
	std::cout << "%SUITE_STARTING% crash" << std::endl;
	std::cout << "%SUITE_STARTED%" << std::endl;

	std::cout << "%TEST_STARTED% Crash (crash)" << std::endl;
	test1();
	std::cout << "%TEST_FINISHED% time=0 Crash (crash)" << std::endl;
	
	std::cout << "%SUITE_FINISHED% time=0" << std::endl;

	return (EXIT_SUCCESS);
}

